﻿using System;
using System.Linq;
using System.Reflection.Emit;
using msilgc.cbuilder.CSyntaxTree;
using msilgc.cbuilder.MSILSyntaxTree;
using msilgc.CSyntaxTree;

namespace msilgc.cbuilder.CBuilder
{
    internal class BooleanBranchTranslator : ITranslator {
        private static void CheckInstrution(Instruction inst) {
            if(!(inst.Inst == OpCodes.Brtrue || inst.Inst == OpCodes.Brtrue_S ||
                 inst.Inst == OpCodes.Brfalse || inst.Inst == OpCodes.Brfalse_S)) {
                     throw new Exception("unexpected instruction: " + inst);
                 }
        }

        public ICStatement TranslateAndAdd(CMethodBody methodBody, CBasicBlock currentBlock, BasicBlock block, Instruction instruction) {
            CheckInstrution(instruction);
            var targetBlock = methodBody.BasicBlocks.First(cBlock => block.TargetsThatAreNotTheNextBlock.Contains(cBlock.MsilBlock));
            var conditionVar = EvaluationStackHelper.PopVariableOffEvaluationStack(currentBlock);
            ICStatement statement;
            if (instruction.Inst == OpCodes.Brtrue || instruction.Inst == OpCodes.Brtrue_S) {
                statement = new BooleanBranchStatement(targetBlock.Label, conditionVar, true);
            } else {
                statement = new BooleanBranchStatement(targetBlock.Label, conditionVar, false);
            }
            currentBlock.Statements.Add(statement);
            return statement;
        }
    }
}